function SpaceUnitConstructor(type, scale) {
    this._type = type;
    this._scale = scale;

    this._rateMm = this._scale / this._MILLIMETER.scale;
    this._maxMm = Number.POSITIVE_INFINITY / this._scale;

    this._rateCm = this._scale >= this._CETIMETER.scale ? this._scale / this._CETIMETER.scale : this._CETIMETER.scale / this._scale;
    this._maxCm = Number.POSITIVE_INFINITY / this._rateCm;

    this._rateDm = this._scale >= this._DICIMETER.scale ? this._scale / this._DICIMETER.scale : this._DICIMETER.scale / this._scale;
    this._maxDm = Number.POSITIVE_INFINITY / this._rateDm;

    this._rateM = this._scale >= this._METER.scale ? this._scale / this._METER.scale : this._METER.scale / this._scale;
    this._maxM = Number.POSITIVE_INFINITY / this._rateM;

    this._rateKm = this._KILOMETER.scale / this._scale;
    this._maxKm = Number.POSITIVE_INFINITY / this._rateKm;
}

SpaceUnitConstructor.prototype._MILLIMETER = {
    scale: 1,
    unit: "毫米"
};

SpaceUnitConstructor.prototype._CETIMETER = {
    scale: 10 * SpaceUnitConstructor.prototype._MILLIMETER.scale,
    unit: "厘米"
};

SpaceUnitConstructor.prototype._DICIMETER = {
    scale: 10 * SpaceUnitConstructor.prototype._CETIMETER.scale,
    unit: "分米"
};

SpaceUnitConstructor.prototype._METER = {
    scale: 10 * SpaceUnitConstructor.prototype._DICIMETER.scale,
    unit: "米"
};

SpaceUnitConstructor.prototype._KILOMETER = {
    scale: 1000 * SpaceUnitConstructor.prototype._METER.scale,
    unit: "千米"
};

SpaceUnitConstructor.prototype.formatToMm = function(distance, digits = -1) {
    return (digits === -1 ? this.toMm(distance) : this.toMm(distance).toFixed(digits)) + SpaceUnitConstructor.prototype._MILLIMETER.unit;
};

SpaceUnitConstructor.prototype.formatToCm = function(distance, digits = -1) {
    return (digits === -1 ? this.toCm(distance) : this.toCm(distance).toFixed(digits)) + SpaceUnitConstructor.prototype._CETIMETER.unit;
};

SpaceUnitConstructor.prototype.formatToDm = function(distance, digits = -1) {
    return (digits === -1 ? this.toDm(distance) : this.toDm(distance).toFixed(digits)) + SpaceUnitConstructor.prototype._DICIMETER.unit;
};

SpaceUnitConstructor.prototype.formatToM = function(distance, digits = -1) {
    return (digits === -1 ? this.toM(distance) : this.toM(distance).toFixed(digits)) + SpaceUnitConstructor.prototype._METER.unit;
};

SpaceUnitConstructor.prototype.formatToKm = function(distance, digits = -1) {
    return (digits === -1 ? this.toKm(distance) : this.toKm(distance).toFixed(digits)) + SpaceUnitConstructor.prototype._KILOMETER.unit;
};

SpaceUnitConstructor.prototype.toMm = function(distance) {
    return this._convert(distance, SpaceUnitConstructor.prototype._MILLIMETER.scale, this._scale, this._maxMm, this._rateMm);
};

SpaceUnitConstructor.prototype.toCm = function(distance) {
    return this._convert(distance, SpaceUnitConstructor.prototype._CETIMETER.scale, this._scale, this._maxCm, this._rateCm);
};

SpaceUnitConstructor.prototype.toDm = function(distance) {
    return this._convert(distance, SpaceUnitConstructor.prototype._DICIMETER.scale, this._scale, this._maxDm, this._rateDm);
};

SpaceUnitConstructor.prototype.toM = function(distance) {
    return this._convert(distance, SpaceUnitConstructor.prototype._METER.scale, this._scale, this._maxM, this._rateM);
};

SpaceUnitConstructor.prototype.toKm = function(distance) {
    return this._convert(distance, SpaceUnitConstructor.prototype._KILOMETER.scale, this._scale, this._maxKm, this._rateKm);
};

SpaceUnitConstructor.prototype._convert = function(distance, dstScale, srcScale, maxAvailableDistance, rate) {
    if (srcScale === dstScale) {
        return distance;
    } else if (srcScale < dstScale) {
        return distance / rate;
    } else if (distance > maxAvailableDistance) {
        return Number.POSITIVE_INFINITY;
    } else if (distance < -maxAvailableDistance) {
        return Number.NEGATIVE_INFINITY;
    } else {
        return distance * rate;
    }
};

export default SpaceUnitConstructor;
